package com.xiang.reggie.web;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiang.reggie.common.Result;
import com.xiang.reggie.dto.SetmealDto;
import com.xiang.reggie.entity.Category;
import com.xiang.reggie.entity.Setmeal;
import com.xiang.reggie.entity.SetmealDish;
import com.xiang.reggie.service.CategoryService;
import com.xiang.reggie.service.SetmealDishService;
import com.xiang.reggie.service.SetmealService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 半山居雾
 * @date 2022/12/17 9:19
 */
@RestController
@RequestMapping("/setmeal")
@Slf4j
@Api(tags = "套餐模块相关的接口")
public class SetmealController {

    @Autowired
    private SetmealService setmealService;
    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private CategoryService categoryService;

    //添加新的套餐时，清空setmealCache  缓存名称下的相关的所有的套餐缓存数据
    @PostMapping
    @CacheEvict(value = "setmealCache",allEntries = true)
    //清除setmealCache名称下,所有的缓存数据
    public Result<String> save(@RequestBody SetmealDto setmealDto) {

        setmealService.saveWithDish(setmealDto);
        return Result.success("新增成功");
    }


    @ApiOperation(value = "分页查询套餐数据的接口方法")
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(name = "page",value = "查询的页码",required = true),
                    @ApiImplicitParam(name = "pageSize",value = "查询的条数",required = true),
                    @ApiImplicitParam(name = "name",value = "套餐名称，查询条件",required = false)
            }

    )
    @GetMapping("/page")
    public Result<Page> queryByPage(int page, int pageSize, String name) {
        Page<Setmeal> setmealPage = new Page<>(page, pageSize);
        Page<SetmealDto> setmealDtoPage = new Page<>();

        //分页查询出list集合封装的数据
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(name != null, Setmeal::getName, name);
        //添加排序条件，根据更新时间降序排列
        queryWrapper.orderByDesc(Setmeal::getUpdateTime);
        setmealService.page(setmealPage, queryWrapper);

        //将分页数据拷贝到dto对象中，不拷贝    套餐对象数据
        BeanUtils.copyProperties(setmealPage, setmealDtoPage, "records");
        //对套餐对象数据进行处理，找出categoryId对应的分类name
        List<Setmeal> records = setmealPage.getRecords();

        //生成了一个属性为dto的records
        List<SetmealDto> setmealDtoList = records.stream().map((item) -> {
            //创建dto对象封装分类名称及copy数据record
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(item, setmealDto);
            //获取分类名称
            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);

            if (category != null) {
                String categoryName = category.getName();
                //设置分类名称给dto对象
                setmealDto.setCategoryName(categoryName);
            }
            return setmealDto;
        }).collect(Collectors.toList());

        setmealDtoPage.setRecords(setmealDtoList);
        return Result.success(setmealDtoPage);

    }


    /**
     * 删除套餐
     *
     * @param ids id
     * @return {@code Result<String>}
     */
    @DeleteMapping()
    @Transactional
    @CacheEvict(value = "setmealCache",allEntries = true)
    public Result<String> deleteSetmeal(@RequestParam List<Long> ids) {

        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Setmeal::getId, ids).eq(Setmeal::getStatus, 0);
        boolean remove = setmealService.remove(queryWrapper);
        if (remove) {
            LambdaQueryWrapper<SetmealDish> qw = new LambdaQueryWrapper<>();
            qw.in(SetmealDish::getSetmealId, ids);
            setmealDishService.remove(qw);
        }

        return remove ? Result.success("删除成功") : Result.error("套餐正在售卖中，不允许删除");
    }

    /**
     * 更新状态
     *
     * @param status 状态
     * @param ids    id
     * @return {@code Result<String>}
     */
    @PostMapping("/status/{status}")
    public Result<String> updateStatus(@PathVariable int status, Long[] ids) {
        LambdaUpdateWrapper<Setmeal> qw = new LambdaUpdateWrapper<>();
        qw.set(Setmeal::getStatus, status);
        qw.in(Setmeal::getId, ids);
        boolean update = setmealService.update(qw);
        return update ? Result.success("修改状态成功") : Result.error("修改状态失败");
    }


    /**
     * 修改套餐前展示数据
     *
     * @param id id
     * @return {@code Result<SetmealDto>}
     */
    @GetMapping("/{id}")
    public Result<SetmealDto> list(@PathVariable Long id) {
        Setmeal setmeal = setmealService.getById(id);

        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId, id);
        List<SetmealDish> setmealDishList = setmealDishService.list(queryWrapper);

        SetmealDto setmealDto = new SetmealDto();
        setmealDto.setSetmealDishes(setmealDishList);
        BeanUtils.copyProperties(setmeal, setmealDto);

        return Result.success(setmealDto);

    }


    /**
     * 修改套餐
     *
     * @param setmealDto setmeal dto
     * @return {@code Result<String>}
     */
    @PutMapping()
    public Result<String> update(@RequestBody SetmealDto setmealDto) {

        setmealService.updateSetmeal(setmealDto);
        return Result.success("修改成功");
    }


    /**
     * 用户端展示套餐
     *
     * @param setmeal setmeal
     * @return {@code Result<List<Setmeal>>}
     */
    @GetMapping("/list")
//    @CachePut(value = "setmealCache", key = "'setmeal-'+#categoryId")
    //功能更强大，先查询缓存是否存在指定key的数据，如果存在直接返回缓存数据，不存在，正常执行
    @Cacheable(value = "setmealCache", key = "'setmeal-'+#categoryId")
    public Result<List<Setmeal>> list(Setmeal setmeal) {
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId());
        queryWrapper.eq(setmeal.getStatus() != null, Setmeal::getStatus, setmeal.getStatus());
        queryWrapper.orderByDesc(Setmeal::getUpdateTime);

        List<Setmeal> list = setmealService.list(queryWrapper);
        return Result.success(list);
    }

}
